---
title: "Best Practices"
group: "Goodies"
groupOrder: 1
---

In order to ensure that `zsa` is used to its full potential, we've collected a few "best" practices. We hope to grow this list as more developers discover new ways of using `zsa`.

1. **Naming multiple calls**:
   - If you need to call multiple server actions, you can name the resulting destructured array based on the action's functionality.
     ```ts 
     const [categories, err1] = await categoriesAction();
     // ...
     const [places, err2] = await placesAction();
     ```

2. **Simple error messages**:
   - When handling errors from server actions, throw the error message directly as a string from the server side:
     ```ts title="actions.ts"
     ...throw "User not found"; //this is within an action
     ```
   - On the client side, you can access the error message using `err.data` and display it using a toast or any other preferred method:
     ```ts 
     const [, err] = await action();

     if (err) {
      // handle error
      toast(err.data);
      return;
     }

     // ...
     ```

3. **Creating actions from procedures**:
   - When creating server actions from procedures, create the procedure first and then chain the `createServerAction()` method:
     ```ts title="good-example.ts"
     const procedure = createServerActionProcedure()/* ... */.createServerAction();

     const action1 = procedure.input(/* ... */);
     const action2 = procedure.input(/* ... */);
     ```
   - Instead of:
     ```ts title="bad-example.ts"
     const action1 = procedure.createServerAction().input(/* ... */);
     const action2 = procedure.createServerAction().input(/* ... */);
     ```


By following these best practices, you can ensure a cleaner and more maintainable codebase when using `zsa`.